import type {
  $WorkFlow, BaseComponent, IObject, OType, PromiseType,
} from '@cscec/udp-ui';
import React, { CSSProperties, MouseEventHandler } from 'react';

/**
 * 自定义表单class页面基础属性
 */
export interface IPageFunction {
  busType?: string;
  nextRoute?: string;
}

export interface IBasePageInstance extends BaseComponent<any, any, any, ICustomHooks> {
  /**
   * 发起送审
   * @param record
   */
  startFlow(record: Record<string, any>): Promise<[Boolean, any]>;
  /**
   * 申请去审
   * @param record
   */
  applyForReview(record: Record<string, any>): Promise<[Boolean, any]>;

  /**
   * 获取工作流Api
   */
  getWorkFlow(): typeof $WorkFlow;

  /**
   * 获取列表的公共属性
   */
  getPublicProperty(): { CheckBySelf: YN; DeleteBySelf: YN; UnCheckBySelf: '1' | '0';[x: string]: any };

  /**
   * 获取单据编码规则
   */
  getBillNoRule(): Array<{ id: string; bizCode: string; tableName: string; noField: string }>;

  /**
   * 获取自定义表单接口微服务名
   */
  getMicroServiceName(): string;
}

type YN = 'Y' | 'N';

export interface IBaseRef {
  /**
   * 获取列表的业务主键
   */
  getBusKey(): string;

  /**
   * 获取组件api
   * @param id
   */
  getCmpApi(id: string): Record<string, Function>;
}

export interface IListPageRef extends IBaseRef {
  /**
   * 刷新列表
   */
  refreshList(): Promise<void>;
}

export interface IDetailPageRef extends IBaseRef {
  /**
   * 验证当前明细数据
   */
  validData(): Promise<boolean>;

  /**
   * 获取当前明细数据
   */
  getAllData(): object;

  /**
   * 获取主表数据
   */
  getMainForm(): IObject;

  quoteSrc(): Promise<void>;
  /**
   * 刷新页面数据状态
   */
  refreshData(): Promise<any>;
}

export type IListPage = IBasePageInstance &
  IListPageRef & {
    openDetail(oType?: OType, record?: IObject, otherQuery?:IObject): Promise<void>;
    setCurrentRecord(record: IObject): void;
    setSelected(config: { selected?: IObject[]; editable?: boolean }): void;
    getSelectedRecord(): IObject[];
    getCapacity(): IObject;
    getCurrentRecord(): Promise<IObject | undefined>;
  };
export type IDetailPage = IBasePageInstance &
  IDetailPageRef & {
    oType: OType;
    Id: string;
    /**
       * @description 保存明细数据
       */
    saveData(): Promise<boolean | void>;
    /**
       * 打开附件
       */
    openAttachment(): Promise<void>;
  };

type hookReturnType<T = object> = PromiseType<T | void>;
type hookReturnTypeWidthFalse = PromiseType<{ params?: object; cancel?: boolean }>;
type listItemRenderReturn =
  | {
    type?: string;
    style?: CSSProperties;
    children: listItemRenderReturn | Array<listItemRenderReturn>;
    onClick?: MouseEventHandler | undefined;
  }
  | string;

export interface ICustomHooks {
  /**
   * @description 列表数据请求前的钩子函数，用于注入额外参数
   */
  transferListReqParams?(defaultParams: object): hookReturnType;

  /**
   * @description 列表数据请求前的钩子函数，用于重写获取列表数据的url地址，可能会在不同tab页情况使用
   */
  overrideListReqURL?(defaultURL: string, defaultParams: object): hookReturnType<string>;

  /**
   * @description 列表数据返回后的钩子（在更新react状态之前执行），用于转换服务端返回的数据结构，转换后的``Record``类型必须符合元数据定义
   */
  transferListData?(result: object): hookReturnType<{ totalRows: number; Record: object[] }>;

  /**
   * @description 删除数据前的钩子函数，用于注入额外参数，返回``{cancel: true}``则取消删除操作
   * @param selectedRecord 当前选择的数据行
   */
  transferDeleteReqParams?(selectedRecord: object[]): hookReturnTypeWidthFalse;

  /**
   * @description 列表数据跳转明细前的钩子函数，用于注入额外参数，返回``{cancel: true}``则取消页面跳转
   * @param args oType 操作类型  record 数据行 defaultParams 默认参数
   */
  transferDetailPageURL?(args: { oType: OType; record?: object; defaultParams: object }): hookReturnTypeWidthFalse;

  /**
   * @description 表单明细数据加载完成后的钩子函数，用于转换服务端返回的数据结构，转化后的结果类型必须符合元数据定义（新增时用于初始化状态）
   * @param defaultState 默认明细数据状态
   * @param payload 其他参数，包括当前元数据配置的url、请求参数data，页面状态oType
   */
  transferDetailData?(
    defaultState: object,
    payload: { data: object; oType: OType }
  ): hookReturnType;

  /**
   * @description 明细数据请求前的参数钩子
   */
  transferDetailReqParams?(params: object): hookReturnType;

  /**
   * @description 表单明细保存数据前的钩子函数，用于注入额外参数，返回``{cancel: true}``则取消保存
   * @param data 准备提交的数据
   */
  transferSaveParams?(data: object): hookReturnTypeWidthFalse;

  /**
   * @description 送审前的钩子函数，用于注入额外参数或重写参数，返回``{cancel: true}``则取消送审
   * @param record 数据行或者主数据
   * @param defaultParams 默认参数
   * @param type 0 送审 1申请去审
   */
  transferStartFlowParams?(param: { record: object, defaultParams: object, type: 0 | 1 }): hookReturnTypeWidthFalse;
}

export interface IPageListProps {
}
